﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace RPG
{
    public class CGUIWindow
    {
        //Private
        private List<CGUIObject> guiObjects;
        private Vector2 windowSize;
        private BoundingBox windowBoundingBox;
        private Vector2 pullWindowOrigin;
        private Vector2 pullMouseOrigin;
        private bool pullBeingPulled = false;
        private Texture2D dotTexture;
        private Texture2D backgroundTexture;
        private bool windowMovable = true;
        private Color backgroundColor;
        private Color borderColor;
        private float borderWidth;

        //Public
        public Vector2 windowPosition;

        public List<CGUIObject> GUIObjects
        {
            get
            {
                return guiObjects;
            }
            set
            {
                throw new Exception("Can't set a Windows GUIObjects");
            }
        }

        //Creates a new GUI Window with the given position and size
        public CGUIWindow(Vector2 _windowPosition, Vector2 _windowSize, Texture2D _texture)
        {
            //Set Aligned Properties
            windowPosition = _windowPosition;
            windowSize = _windowSize;
            dotTexture = _texture;
            backgroundTexture = _texture;
            Vector3 windowBoundingBoxMin = new Vector3(windowPosition.X, windowPosition.Y, 0);
            Vector3 windowBoundingBoxMax = windowBoundingBoxMin + new Vector3(windowSize.X, windowSize.Y, 0);
            windowBoundingBox = new BoundingBox(windowBoundingBoxMin, windowBoundingBoxMax);
            //Set Default Properties
            guiObjects = new List<CGUIObject>();
            backgroundColor = Color.Red;
            borderColor = Color.Blue;
            borderWidth = 1f;
        }

        //Called on draw
        public void Draw(SpriteBatch spriteBatch)
        {
            //Draw itself and Members
            Primitives2D.FillRect(spriteBatch, windowPosition, windowPosition + windowSize, backgroundColor);
            foreach (CGUIObject guiObject in guiObjects)
            {
                if (guiObject != null)
                    guiObject.Draw(spriteBatch);
            }
            Primitives2D.DrawRect(spriteBatch, windowPosition, windowPosition + windowSize, 1f, borderColor);
        }

        //Called on update
        public void Update(GameTime gameTime, MouseState oldMouseState, MouseState newMouseState)
        {
            bool memberIntersectsMouse = false;
            //Check if the Left Button was pressed on the window and initialize the Pull
            if (windowMovable)
            {
                Vector3 mousePos = new Vector3(newMouseState.X, newMouseState.Y, 0);
                BoundingBox mouseBoundingBox = new BoundingBox(mousePos, mousePos);
                foreach (CGUIObject guiObject in guiObjects)
                {
                    if (guiObject != null)
                    {
                        if (mouseBoundingBox.Intersects(guiObject.boundingBox))
                        {
                            memberIntersectsMouse = true;
                            break;
                        }
                    }
                }
                if (!memberIntersectsMouse)
                {
                    if (oldMouseState.LeftButton == ButtonState.Released && newMouseState.LeftButton == ButtonState.Pressed)
                    {
                        if (mouseBoundingBox.Intersects(windowBoundingBox))
                        {
                            pullWindowOrigin = windowPosition;
                            pullMouseOrigin = new Vector2(newMouseState.X, newMouseState.Y);
                            pullBeingPulled = true;
                        }
                    }
                }
            }
            //Move Window while pulling
            if (oldMouseState.LeftButton == newMouseState.LeftButton && oldMouseState.LeftButton == ButtonState.Pressed
                && pullBeingPulled)
            {
                windowPosition = pullWindowOrigin - (pullMouseOrigin - new Vector2(newMouseState.X, newMouseState.Y));
            }
            //End of pull
            if (oldMouseState.LeftButton == ButtonState.Pressed && newMouseState.LeftButton == ButtonState.Released)
            {
                pullWindowOrigin = Vector2.Zero;
                pullMouseOrigin = Vector2.Zero;
                pullBeingPulled = false;
            }
            Vector3 windowBoundingBoxMin = new Vector3(windowPosition.X, windowPosition.Y, 0);
            Vector3 windowBoundingBoxMax = windowBoundingBoxMin + new Vector3(windowSize.X, windowSize.Y, 0);
            windowBoundingBox = new BoundingBox(windowBoundingBoxMin, windowBoundingBoxMax);
            //Update Members
            foreach (CGUIObject guiObject in guiObjects)
            {
                if (guiObject != null)
                {
                    Vector3 boundingBoxMin = new Vector3(windowPosition + guiObject.position, 0);
                    Vector3 boundingBoxMax = boundingBoxMin + new Vector3(guiObject.size, 0);
                    guiObject.boundingBox = new BoundingBox(boundingBoxMin, boundingBoxMax);
                    guiObject.Update(gameTime, oldMouseState, newMouseState);
                }
            }
        }

        //Adds a guiObject to the window
        public void Add(CGUIObject guiObject)
        {
            guiObjects.Add(guiObject);
            guiObject.parentWindow = this;
        }

        //Sets
        public void SetWindowPosition(Vector2 whichPosition) { windowPosition = whichPosition; }
        public void SetWindowSize(Vector2 whichSize) { windowSize = whichSize; }
        public void SetBorderColor(Color whichColor) { borderColor = whichColor; }
        public void SetBackgroundColor(Color whichColor) { backgroundColor = whichColor; }
        public void SetWindowMovable(bool isMovable) { windowMovable = isMovable; }
        public void SetBorderWidth(float whichWidth) { borderWidth = whichWidth; }
        public void SetBackgroundTexture(Texture2D whichTexture) { backgroundTexture = whichTexture; }
    }
}
